图论-回溯-八皇后

八皇后问题

八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种计算机语言可以解决此问题。

  题解:

 1 /*不列出情况*/
 2 
 3 #include<stdio.h>
 4 #define N 8
 5 int tot=0;
 6 int vis[3][15]= {0};
 7 void search(int cur)
 8 {
 9 int i,j;
10 if(cur==N)
11 tot++;
12 else
13 for(i=0; i<N; i++) //cur代表行,i代表列
14 {
15 if(!vis[0][i]&&!vis[1][cur+i]&&!vis[2][cur-i+N])//在同一主对角线上的元素的特点是行减列的值相同,在同一副对角线上的元素的特点是行加列的值相同
16 {
17   vis[0][i]=vis[1][cur+i]=vis[2][N+cur-i]=1;
18   search(cur+1);
19   vis[0][i]=vis[1][cur+i]=vis[2][N+cur-i]=0 ;
20 }
21 }
22 }
23 int main()
24 {
25 
26 search(0);
27 printf("八皇后摆法总数: %d\n",tot);
28 return 0;
29 }

 

或:

 1 /*列出各种情况:*/
 2 
 3 #include<stdio.h>
 4 int chess[8][8]= {0};
 5 int a[8],b[15],c[15];//分别代表列,富对角线,主对角线
 6 int sum=0; //统计所有摆法
 7 void PutQueen(int n)
 8 {
 9 int col,i,j;
10 for(col=0; col<8; col++) //从第零列到第8列枚举
11 {
12 if(a[col]&& b[n+col] && c[n-col+7]) //判断安全位置
13 {
14 chess[n][col]=1; //放置皇后
15 a[col]=0;
16 b[n+col]=0;
17 c[n-col+7]=0;//和算法书上的区别:这里是先进行判断,整个程序都是在安全位置的前提下进行的,而算法书上是后进行判断所以这里到7就可以确定
18 if(n==7)
19 {
20 sum++;
21 printf("第%d种可能的摆法:\n",sum); //输出皇后摆法
22 for(i=0; i<8; i++)
23 {
24 printf("\t\t");
25 for(j=0; j<8; j++)
26 printf("%d ",chess[i][j]);
27 printf("\n");
28 }
29 printf("\n");
30 if(sum%10==0) //每输出十种暂停因为太多,一次性输出的话看不全
31 {
32 printf("按回车键继续……");
33 getchar();
34 }
35 }
36 else
37 PutQueen(n+1); //递归
38 chess[n][col]=0; //取消皇后
39 b[n+col]=1;
40 c[n-col+7]=1;
41 a[col]=1;
42 }
43 }
44 }
45 int main()
46 {
47 int i;
48 for(i=0; i<8; ++i)
49 a[i]=1;
50 for(i=0; i<15; ++i)
51 {
52 b[i]=1;
53 c[i]=1;
54 }
55 PutQueen(0);
56 printf("八皇后摆法总数: %d\n",sum);
57 return 0;
58 }

 

 

 

 

posted @ 2015-01-09 09:09  zach96  阅读(557)  评论(0编辑  收藏  举报